#include "com_voe_VoECodec.h"
#include "jni_api.h"
#include "OutputParam.h"
#include "voe_codec.h"

webrtc::CodecInst* convert(JNIEnv* env, jobject obj, webrtc::CodecInst* codecInst)
{
	if(obj)
	{
		jclass cls = JniHelper::getClassByObject(env, obj);
		codecInst->pltype = JniHelper::getIntField(env, obj, JniHelper::getFieldID(env, cls, "pltype", "I"));
		strcpy(codecInst->plname, JniHelper::j2c_string(env, (jstring)JniHelper::getObjectField(env, obj, JniHelper::getFieldID(env, cls, "plname", "Ljava/lang/String;"))).c_str());
		codecInst->plfreq = JniHelper::getIntField(env, obj, JniHelper::getFieldID(env, cls, "plfreq", "I"));
		codecInst->pacsize = JniHelper::getIntField(env, obj, JniHelper::getFieldID(env, cls, "pacsize", "I"));
		codecInst->channels = JniHelper::getIntField(env, obj, JniHelper::getFieldID(env, cls, "channels", "I"));
		codecInst->rate = JniHelper::getIntField(env, obj, JniHelper::getFieldID(env, cls, "rate", "I"));
		return codecInst;
	}
	return 0;
}

/*
* Class:     com_voe_VoECodec
* Method:    GetInterface
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_com_voe_VoECodec_GetInterface
	(JNIEnv* env, jclass cls, jlong p_voiceEngine)
{
	return (jlong)webrtc::VoECodec::GetInterface((webrtc::VoiceEngine*)p_voiceEngine);
}

/*
* Class:     com_voe_VoECodec
* Method:    Release
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_Release
	(JNIEnv* env, jclass cls, jlong p)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	return pVoECodec->Release();
}

/*
* Class:     com_voe_VoECodec
* Method:    NumOfCodecs
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_NumOfCodecs
	(JNIEnv* env, jclass cls, jlong p)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	return pVoECodec->NumOfCodecs();
}

/*
* Class:     com_voe_VoECodec
* Method:    GetCodec
* Signature: (JILcom/voe/common/OutputParam;)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_GetCodec
	(JNIEnv* env, jclass cls, jlong p, jint index, jobject obj)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	webrtc::CodecInst codecInst = {0};
	jint result = pVoECodec->GetCodec(index, codecInst);
	if(result == 0)
	{
		JniOutputBuilder job(env);
		OutputParam param(env, obj);
		param.setArray(job.add(codecInst.pltype).add(std::string(codecInst.plname)).add(codecInst.plfreq)
			.add(codecInst.pacsize).add(codecInst.channels).add(codecInst.rate).getOutput());
	}
	return result;
}

/*
* Class:     com_voe_VoECodec
* Method:    SetSendCodec
* Signature: (JILcom/voe/common/CodecInst;)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_SetSendCodec
	(JNIEnv* env, jclass cls, jlong p, jint channel, jobject obj)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	webrtc::CodecInst codecInst = {0};
	convert(env, obj, &codecInst);
	return pVoECodec->SetSendCodec(channel, codecInst);
}

/*
* Class:     com_voe_VoECodec
* Method:    GetSendCodec
* Signature: (JILcom/voe/common/OutputParam;)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_GetSendCodec
	(JNIEnv* env, jclass cls, jlong p, jint channel, jobject obj)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	webrtc::CodecInst codecInst = {0};
	jint result = pVoECodec->GetSendCodec(channel, codecInst);
	if(result == 0)
	{
		JniOutputBuilder job(env);
		OutputParam param(env, obj);
		param.setArray(job.add(codecInst.pltype).add(std::string(codecInst.plname)).add(codecInst.plfreq)
			.add(codecInst.pacsize).add(codecInst.channels).add(codecInst.rate).getOutput());
	}
	return result;
}

/*
* Class:     com_voe_VoECodec
* Method:    SetSecondarySendCodec
* Signature: (JILcom/voe/common/CodecInst;I)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_SetSecondarySendCodec
	(JNIEnv* env, jclass cls, jlong p, jint channel, jobject obj, jint red_payload_type)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	webrtc::CodecInst codecInst = {0};
	convert(env, obj, &codecInst);
	return pVoECodec->SetSecondarySendCodec(channel, codecInst, red_payload_type);
}

/*
* Class:     com_voe_VoECodec
* Method:    RemoveSecondarySendCodec
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_RemoveSecondarySendCodec
	(JNIEnv* env, jclass cls, jlong p, jint channel)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	return pVoECodec->RemoveSecondarySendCodec(channel);
}

/*
* Class:     com_voe_VoECodec
* Method:    GetSecondarySendCodec
* Signature: (JILcom/voe/common/OutputParam;)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_GetSecondarySendCodec
	(JNIEnv* env, jclass cls, jlong p, jint channel, jobject obj)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	webrtc::CodecInst codecInst = {0};
	jint result = pVoECodec->GetSecondarySendCodec(channel, codecInst);
	if(result == 0)
	{
		JniOutputBuilder job(env);
		OutputParam param(env, obj);
		param.setArray(job.add(codecInst.pltype).add(std::string(codecInst.plname)).add(codecInst.plfreq)
			.add(codecInst.pacsize).add(codecInst.channels).add(codecInst.rate).getOutput());
	}
	return result;
}

/*
* Class:     com_voe_VoECodec
* Method:    GetRecCodec
* Signature: (JILcom/voe/common/OutputParam;)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_GetRecCodec
	(JNIEnv* env, jclass cls, jlong p, jint channel, jobject obj)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	webrtc::CodecInst codecInst = {0};
	jint result = pVoECodec->GetRecCodec(channel, codecInst);
	if(result == 0)
	{
		JniOutputBuilder job(env);
		OutputParam param(env, obj);
		param.setArray(job.add(codecInst.pltype).add(std::string(codecInst.plname)).add(codecInst.plfreq)
			.add(codecInst.pacsize).add(codecInst.channels).add(codecInst.rate).getOutput());
	}
	return result;
}

/*
* Class:     com_voe_VoECodec
* Method:    SetISACInitTargetRate
* Signature: (JIIZ)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_SetISACInitTargetRate
	(JNIEnv* env, jclass cls, jlong p, jint channel, jint rateBps, jboolean useFixedFrameSize)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	return pVoECodec->SetISACInitTargetRate(channel, rateBps, useFixedFrameSize!=0);
}

/*
* Class:     com_voe_VoECodec
* Method:    SetISACMaxRate
* Signature: (JII)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_SetISACMaxRate
	(JNIEnv* env, jclass cls, jlong p, jint channel, jint rateBps) 
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	return pVoECodec->SetISACMaxRate(channel, rateBps);
}

/*
* Class:     com_voe_VoECodec
* Method:    SetISACMaxPayloadSize
* Signature: (JII)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_SetISACMaxPayloadSize
	(JNIEnv* env, jclass cls, jlong p, jint channel, jint sizeBytes)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	return pVoECodec->SetISACMaxPayloadSize(channel, sizeBytes);
}

/*
* Class:     com_voe_VoECodec
* Method:    SetRecPayloadType
* Signature: (JILcom/voe/common/CodecInst;)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_SetRecPayloadType
	(JNIEnv* env, jclass cls, jlong p, jint channel, jobject obj)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	webrtc::CodecInst codecInst = {0};
	convert(env, obj, &codecInst);
	return pVoECodec->SetRecPayloadType(channel, codecInst);
}

/*
* Class:     com_voe_VoECodec
* Method:    GetRecPayloadType
* Signature: (JILcom/voe/common/OutputParam;)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_GetRecPayloadType
	(JNIEnv* env, jclass cls, jlong p, jint channel, jobject obj)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	webrtc::CodecInst codecInst = {0};
	jint result = pVoECodec->GetRecPayloadType(channel, codecInst);
	if(result == 0)
	{
		JniOutputBuilder job(env);
		OutputParam param(env, obj);
		param.setArray(job.add(codecInst.pltype).add(std::string(codecInst.plname)).add(codecInst.plfreq)
			.add(codecInst.pacsize).add(codecInst.channels).add(codecInst.rate).getOutput());
	}
	return result;
}

/*
* Class:     com_voe_VoECodec
* Method:    SetSendCNPayloadType
* Signature: (JIII)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_SetSendCNPayloadType
	(JNIEnv* env, jclass cls, jlong p, jint channel, jint type, jint frequency)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	return pVoECodec->SetSendCNPayloadType(channel, type, (webrtc::PayloadFrequencies)frequency);
}

/*
* Class:     com_voe_VoECodec
* Method:    SetVADStatus
* Signature: (JIZIZ)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_SetVADStatus
	(JNIEnv* env, jclass cls, jlong p, jint channel, jboolean enable, jint mode, jboolean disableDTX)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	return pVoECodec->SetVADStatus(channel, enable!=0, (webrtc::VadModes)mode, disableDTX!=0);
}

/*
* Class:     com_voe_VoECodec
* Method:    GetVADStatus
* Signature: (JILcom/voe/common/OutputParam;)I
*/
JNIEXPORT jint JNICALL Java_com_voe_VoECodec_GetVADStatus
	(JNIEnv* env, jclass cls, jlong p, jint channel, jobject obj)
{
	webrtc::VoECodec* pVoECodec = (webrtc::VoECodec*)p;
	bool enabled, disabledDTX;
	webrtc::VadModes mode;
	jint result = pVoECodec->GetVADStatus(channel, enabled, mode, disabledDTX);
	if(result == 0)
	{
		JniOutputBuilder job(env);
		OutputParam param(env, obj);
		param.setArray(job.add(enabled).add((int)mode).add(disabledDTX).getOutput());
	}
	return result;
}

